package io.renren.modules.avanotes.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.utils.BizUtils;
import io.renren.common.utils.DateUtils;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import io.renren.common.vo.output.NextWordVo;
import io.renren.common.vo.output.ReciteWordAggVo;
import io.renren.common.vo.output.SubtitleDetailsVo;
import io.renren.config.BizConfig;
import io.renren.config.TXYCosConfig;
import io.renren.modules.avanotes.dao.ReciteRecordDao;
import io.renren.modules.avanotes.dao.VocabularyDao;
import io.renren.modules.avanotes.entity.ReciteRecordEntity;
import io.renren.modules.avanotes.entity.SubtitleDetailsEntity;
import io.renren.modules.avanotes.entity.VocabularyEntity;
import io.renren.modules.avanotes.service.ReciteRecordService;
import io.renren.modules.avanotes.service.SubtitleDetailsService;
import io.renren.modules.oss.cloud.COSCloudStorageService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;


//@Service("reciteRecordService")//默认只有一个实现，那就不写名称了直接使用默认的名称！
@Service
public class ReciteRecordServiceImpl extends ServiceImpl<ReciteRecordDao, ReciteRecordEntity> implements ReciteRecordService {

    @Value("${resource.pre.path}")
    private String resourcePathPre;

    @Autowired
    COSCloudStorageService cosCloudStorageService;
    @Autowired
    private SubtitleDetailsService subtitleDetailsService;
    @Autowired
    VocabularyDao vDao;
    @Autowired
    TXYCosConfig cosConfig;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<ReciteRecordEntity> page = this.page(
                new Query<ReciteRecordEntity>().getPage(params),
                new QueryWrapper<ReciteRecordEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public ReciteWordAggVo genAggNumberByUserId(long userId) {
        Integer today = Integer.parseInt(DateUtils.format(new Date(), BizConfig.RECITE_TIME_FORMAT));
        //1.今日已学
        int todayNum = this.count(new QueryWrapper<ReciteRecordEntity>().eq(ReciteRecordEntity.CN_TU_ID, userId).eq(ReciteRecordEntity.CN_DATE, today));
        //2.今日需复习
        //TODO 待设计
        //3.全部已学
        int totalNum = this.count(new QueryWrapper<ReciteRecordEntity>().eq(ReciteRecordEntity.CN_TU_ID, userId));
        ReciteWordAggVo vo = new ReciteWordAggVo(todayNum, 0, totalNum);
        return vo;
    }

    /**
     * 1. 从记录表中获取该用户最大的 v_id
     * 2. 从 vocabulary 中获取下一个单词（select * from `vocabulary` where is_match=1 and id>{num} limit 1）
     *
     * @param userId
     * @return
     */
    @Override
    public NextWordVo nextWord(long userId) {
        NextWordVo vo = new NextWordVo();
        //获取当前用户已经记录的单词ID
        VocabularyEntity nextMatchById = getNextVocabularyByUserId(userId);
        if (nextMatchById == null) {
            //没有单词了
            return vo;
        }
        makeUpNextWordVoByVocEntity(vo, nextMatchById);
        return vo;
    }


    @Override
    public NextWordVo recordAndNextWord(long userId) {
        NextWordVo vo = new NextWordVo();
        VocabularyEntity nextMatchById = getNextVocabularyByUserId(userId);
        if (nextMatchById == null) {
            //已经背完
            return vo;
        }
        //记录当前数据
        Integer today = Integer.parseInt(DateUtils.format(new Date(), BizConfig.RECITE_TIME_FORMAT));
        ReciteRecordEntity entity = new ReciteRecordEntity(userId, nextMatchById.getId(), today);
        this.save(entity);
        //下一个单词
        VocabularyEntity vocabularyEntity = vDao.getNextMatchById(nextMatchById.getId() + 1);
        makeUpNextWordVoByVocEntity(vo, vocabularyEntity);
        return vo;
    }

    @Override
    public PageUtils searchPageRecordingVocByUserId(Integer userId, Integer pageIndex) {
        VocabularyEntity vocEntity = getNextVocabularyByUserId(userId);
        //进行分页查询
        PageUtils pageUtils = getPageUtils(vocEntity.getWord(), pageIndex, 2);
        return pageUtils;
    }


    //region privatelocalmarkdownnotes


    private VocabularyEntity getNextVocabularyByUserId(long userId) {
        Long vIdByUserId = this.baseMapper.getMaxVIdByUserId(userId);
        return vDao.getNextMatchById(vIdByUserId == null ? 0 : vIdByUserId);
    }

    /**
     * 通过 VocabularyEntity 组装 NextWordVo
     *
     * @param vo
     * @param nextMatchById
     */
    private void makeUpNextWordVoByVocEntity(NextWordVo vo, VocabularyEntity nextMatchById) {
        vo.setWord(nextMatchById.getWord());
        //生成解释
        BizUtils.genNextWordVoExplanationListByExplanation(vo, nextMatchById.getExplanation());
        //生成本地路径
//        BizUtils.genNextWordVoPronunciationPathByLocal(vo, nextMatchById.getPronunciationRelativePath(), resourcePathPre);
        if (StringUtils.isNotBlank(nextMatchById.getCoskey())) {
            //这是给出长时间有效的链接
            //vo.setPronunciationPath(cosConfig.getCConfig().getQcloudDomain() + nextMatchById.getCoskey());
            //这是给出十分钟有效期的链接
            //String presignedURL = cosCloudStorageService.getPresignedURL(entity.getCoskey(), 10, BizUtils.getDefaultStoreHeaders(), new HashMap<>());
            String presignedURL = cosCloudStorageService.getPresignedURL(nextMatchById.getCoskey(), 10, new HashMap<>(), BizUtils.getDefaultStoreParams());
            vo.setPronunciationPath(presignedURL.replace(BizUtils.WX_RESOURCE_PARAM, ""));
        }
        //获取视频分页数据
        //生成首字母大写的英文
        PageUtils pageUtils = getPageUtils(vo.getWord(), 1, 2);
        vo.setPage(pageUtils);
    }

    /**
     * 查询 word 的分页数据
     *
     * @param word
     * @param pageIndex
     * @param pageLimit
     * @return 返回Page List(SubtitleDetailsVo)
     */
    private PageUtils getPageUtils(String word, int pageIndex, int pageLimit) {
        String nWord = BizUtils.genFirstLetterUpperWord(word);
        Map<String, Object> pageParam = BizUtils.getPageParam(pageIndex, pageLimit);
        pageParam.put(BizConfig.SEARCH_KEY, nWord);
        PageUtils pageUtils = subtitleDetailsService.searchPage(pageParam);
        //将单词进行高亮处理：首字母大写 + 全部小写
        List<SubtitleDetailsEntity> list = (List<SubtitleDetailsEntity>) pageUtils.getList();
        List<SubtitleDetailsVo> resList = new ArrayList<>();
        for (SubtitleDetailsEntity entity : list) {
            //1. 第一种直接生成高亮的前端标签脚本——失败！
//            String rep = entity.getEnglish().replace(nWord, BizConfig.WX_HIGHLIGHT_LABEL_PRE + nWord + BizConfig.WX_HIGHLIGHT_LABEL_POST)
//                    .replace(vo.getWord(), BizConfig.WX_HIGHLIGHT_LABEL_PRE + vo.getWord() + BizConfig.WX_HIGHLIGHT_LABEL_POST);
//            entity.setEnglish(rep);
            //2. 将第一个高亮关键词进行分割
            SubtitleDetailsVo detailsVo = new SubtitleDetailsVo();
            BeanUtils.copyProperties(entity, detailsVo);
            String english = entity.getEnglish();
            int hlIndex = english.toLowerCase().indexOf(word.toLowerCase());
            detailsVo.setHLPre(english.substring(0, hlIndex));
            int eIndex = hlIndex + nWord.length();
            detailsVo.setHLWord(english.substring(hlIndex, eIndex));
            detailsVo.setHLPost(english.substring(eIndex));

            //设置预签名地址
            //String presignedURL = cosCloudStorageService.getPresignedURL(entity.getCoskey(), 10, BizUtils.getDefaultStoreHeaders(), new HashMap<>());
            String presignedURL = cosCloudStorageService.getPresignedURL(entity.getCoskey(), 10, new HashMap<>(), BizUtils.getDefaultStoreParams());
            detailsVo.setPath(presignedURL.replace(BizUtils.WX_RESOURCE_PARAM, ""));
            resList.add(detailsVo);
        }
        pageUtils.setList(resList);
        return pageUtils;
    }
    //endregion
}